<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { shuffleArray, swapElements, isArraySorted } from '@/utils'

const props = defineProps<{
  text: string[]
}>()

const emits = defineEmits(['success'])

const wordList = reactive<number[]>([])
watch(
  computed(() => props.text),
  (newValue) => {
    wordList.push(
      ...shuffleArray(Array.from({ length: newValue.length }, (_, i) => i))
    )
  }
)

const sortBoard = ref<HTMLElement | null>(null)
let currentDrag: HTMLElement | null = null
let startIndex = 0
let dragging = false
const startPoint = { x: 0, y: 0 }
const sortRect: DOMRect[] = []

onMounted(() => {
  sortBoard.value?.addEventListener('touchstart', (e) => {
    currentDrag = e.target as HTMLElement

    if (currentDrag !== sortBoard.value) {
      dragging = true
      startIndex = [...sortBoard.value!.children].indexOf(currentDrag)
      startPoint.x = e.touches[0].clientX
      startPoint.y = e.touches[0].clientY
      currentDrag?.classList.add('moving')
      for (const item of [...sortBoard.value!.children]) {
        sortRect.push(item.getBoundingClientRect())
      }
    }
  })

  sortBoard.value?.addEventListener('touchmove', (e) => {
    if (!dragging) return

    e.preventDefault()
    const currentPoint = { x: e.touches[0].clientX, y: e.touches[0].clientY }
    currentDrag!.style.transform = `translate(${currentPoint.x - startPoint.x}px,${currentPoint.y - startPoint.y}px)`
  })

  sortBoard.value?.addEventListener('touchend', async () => {
    if (!dragging) return

    // currentDrag = e.target as HTMLElement
    const currentTransform = currentDrag!.style.transform

    const currentRect = currentDrag?.getBoundingClientRect()!
    const targetIndex = isInRect(currentRect)(sortRect)

    if (targetIndex !== -1 && targetIndex !== startIndex) {
      swapElements(wordList, startIndex, targetIndex)
      await new Promise((resolve) => setTimeout(resolve, 1))
      currentDrag!.style.transform = currentTransform
      await new Promise((resolve) => setTimeout(resolve, 50))
      currentDrag!.classList.remove('moving')
      currentDrag!.style.transform = `translate(0,0)`
      console.log(currentDrag)
      currentDrag!.style.zIndex = '1'
      await new Promise((resolve) => setTimeout(resolve, 2000))
      currentDrag!.style.removeProperty('z-index')
      console.log(currentDrag!.style.zIndex)
    }

    sortRect.splice(0)

    dragging = false

    if (isArraySorted(wordList)) {
      setTimeout(() => {
        ElMessage({
          message: '恭喜你，完成排序',
          type: 'warning',
        })

        emits('success')
      }, 500)
    }
  })

  // sortBoard.value?.addEventListener('dragstart', (e) => {
  //   const target = e.target as HTMLElement
  //   setTimeout(() => {
  //     target.classList.add('moving')
  //   }, 0)
  //   currentDrag = target
  // })
  // sortBoard.value?.addEventListener('dragover', (e) => e.preventDefault())
  // sortBoard.value?.addEventListener('dragenter', (e) => {
  //   e.preventDefault()
  //   const target = e.target as HTMLElement
  //   if (target === currentDrag || target === sortBoard.value) {
  //     return
  //   }
  //   const children = Array.from(sortBoard.value?.children || [])
  //   if (children.indexOf(currentDrag!) > children.indexOf(target)) {
  //     sortBoard.value?.insertBefore(currentDrag!, target)
  //   } else {
  //     sortBoard.value?.insertBefore(currentDrag!, target.nextSibling)
  //   }
  // })
  // sortBoard.value?.addEventListener('dragend', (e) => {
  //   const target = e.target as HTMLElement
  //   target.classList.remove('moving')
  // })
})

const isInRect = (sourceRect: DOMRect) => {
  return (rectList: DOMRect[]) => {
    for (let i = 0; i < rectList.length; i++) {
      const rect = rectList[i]
      if (
        Math.max(sourceRect.left, rect.left) <=
          Math.min(sourceRect.right, rect.right) &&
        Math.max(sourceRect.top, rect.top) <=
          Math.min(sourceRect.bottom, rect.bottom)
      ) {
        return i
      }
    }
    return -1
  }
}
</script>

<template>
  <div class="sort-board" ref="sortBoard">
    <transition-group name="sort-wrapper">
      <span
        v-for="(v, i) in wordList"
        :key="i"
        :class="v === i ? 'success' : ''"
        class="sort-item"
        draggable="true"
        >{{ text[v] }}</span
      >
    </transition-group>
  </div>
</template>

<style scoped>
.sort-board {
  max-height: 80vh;
  max-width: 100vw;
  display: flex;
  flex-wrap: wrap;
  overflow: visible;
}

.sort-item {
  position: relative;
  font-family: 'Georgia', Times, 'Times New Roman', serif;
  font-size: 1.5rem;
  margin: 0.5rem 0.4rem;
  padding: 0.7rem 0.7rem;
  border-radius: 0.5em;
  box-shadow:
    6px 6px 12px #c5c5c5,
    -6px -6px 12px #ffffff;
  backdrop-filter: blur(2px);
  user-select: none;
}

/* .sort-wrapper-move:not(.moving) {
  transition: all 2s ease-in;
} */
.sort-item:not(.moving) {
  transition: all 2s ease-in;
}

.sort-item.moving {
  background: transparent;
  z-index: 1;
}

.success {
  color: #67c23a;
  text-shadow: 0 0 30px #67c23a;
}

@media screen and (max-width: 768px) {
}
</style>
